package utils

import (
	"flag"
	"log"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"
)

func forkNewProcess() {
	// 日志
	var logger *log.Logger
	logFile, err := os.OpenFile("logs/daemon.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err == nil {
		defer func(logFile *os.File) {
			err := logFile.Close()
			if err != nil {
				return
			}
		}(logFile)
		logger = log.New(logFile, "", 0)
	} else {
		logger = log.New(os.Stdout, "", 0)
	}
	logger.Println(time.Now().Format(time.RFC3339), "fork new worker process and daemon process...")

	// 启动工作进程
	cmd := exec.Command(os.Args[0])
	err1 := cmd.Start()
	if err1 != nil {
		log.Println("err:", err1)
		return
	}
	var workerPid = cmd.Process.Pid
	log.Println("[WORKER PID]", workerPid)

	// 启动守护进程
	cmd2 := exec.Command(os.Args[0], "-w="+strconv.Itoa(workerPid))
	err2 := cmd2.Start()
	if err2 != nil {
		log.Println("err:", err2)
		return
	}
	var daemonPid = cmd2.Process.Pid
	log.Println("[DAEMON PID]", daemonPid)

	// 退出
	os.Exit(0)
}

func InitDaemon() {
	var daemon = flag.Bool("d", false, "run app as a daemon with -d=true")
	var workerPid = flag.Int("w", 0, "the pid of worker process with -w=123")

	if !flag.Parsed() {
		flag.Parse()
	}
	if *daemon {
		forkNewProcess()
		return
	}

	if *workerPid > 0 {
		// 检查PID是否存在
		for {
			// 延迟一秒
			time.Sleep(1 * time.Second)

			var pidExists = false
			cmd := exec.Command("ps", strconv.Itoa(*workerPid))
			out, err := cmd.Output()
			if err == nil {
				for _, line := range strings.Split(string(out), "\n") {
					if strings.HasPrefix(strings.TrimSpace(line), strconv.Itoa(*workerPid)+" ") {
						pidExists = true
						break
					}
				}
			}

			if !pidExists {
				// 重新启动
				forkNewProcess()
				return
			}
		}
	}
}
